/*!
 * imconfig v0.0.1
 * (c) 2016 imconfig
 */
! function(global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.IMconfig = factory());
}(this, function() {
    'use strict';
    var err = 0;

    //function
    function ChatUI(obj) {
        if (!obj) {
            obj = {};
        }
        if (!('id' in obj)) {
            obj.id = 'imconfig_container';
        }
        this.is_imconfig = true; //声明
        this.obj = obj;
        this.lis = [];
        this.MaxLisNumber = 100;
        this.getHTML(); //this.html;
        this.styleLink = __uri('/src/css/index.scss');
        this.socket_url = '//cdn.bootcss.com/socket.io/1.4.6/socket.io.min.js';
        this.loadUI();
    }

    ChatUI.prototype.loadUI = function(justLoadJS) {
        var that = this;
        if (justLoadJS) {
            loadJS();
        } else {
            getCSS(this.styleLink, loadJS);
        }

        function loadJS() {
            if (!justLoadJS) {
                that.style = this;
            }
            if (typeof require === 'function' && typeof define === 'function' && define.amd) {
                require([that.socket_url], function(io){
                    that.getContainer(that.obj.id);
                    that.loadIO(io);
                });
            } else {
                getJs(that.socket_url, function() {
                    that.script = this;
                    that.getContainer(that.obj.id);
                    that.loadIO(window.io);
                });
            }
        }
    };
    ChatUI.prototype.loadIO = function(io) {
        if (checkError()) {
            return;
        }
        if (typeof io === 'function') {
            this.io = new Chat(io, this);
        } else if (typeof this.style !== "object") {
            err++;
            this.loadUI();
        } else if (typeof this.script !== "object") {
            err++;
            this.loadUI(true);
        }
    };
    ChatUI.prototype.getContainer = function(id) {
        //get container
        var that = this;
        this.container = document.getElementById(id);
        if (!this.container) {
            this.container = document.createElement('div');
            this.container.id = id;
            document.body.appendChild(this.container);
        }
        this.container.className += 'imconfig-style-container';
        this.container.innerHTML = this.html;
        this.ul = this.container.querySelector('.imconfig-style-content-ul');
        this.edit = this.container.querySelector('.imconfig-style-edit');
        this.submit = this.container.querySelector('.imconfig-style-input-submit');
        this.info = this.container.querySelector('.imconfig-style-self-msg');
        this.count = this.container.querySelector('.imconfig-style-control-count');
        this.lock = this.container.querySelector('.imconfig-style-control-lock');
        this.lockText = this.lock.querySelector('.imconfig-style-control-lock-text');
        this.edit.addEventListener('keyup', function(e) {
            if (e.keyCode === 13 && e.ctrlKey === true) {
                e.preventDefault();
                e.stopPropagation();
                that.chat();
                return false;
            }
        });
        this.submit.addEventListener('click', function(e) {
            that.chat();
        });
        this.lock.addEventListener('click', function(e) {
            that.lockRoller = !that.lockRoller;
            if (that.lockRoller) {
                that.lock.className = 'imconfig-style-control-lock imconfig-style-control-lock-active';
                that.lockText.innerText = '锁屏';
            } else {
                that.lock.className = 'imconfig-style-control-lock';
                that.lockText.innerText = '滚屏';
            }
        });
    };
    ChatUI.prototype.chat = function() {
        var that = this;
        var text = this.edit.innerText.replace(/\n/g, ' ');
        if (text.trim() === '') {
            return;
        }
        this.submit.className = 'imconfig-style-input-submit imconfig-style-input-submit-active';
        this.io.chat(text, function(err) {
            if (err !== 'error') {
                that.edit.innerText = '';
            }
            var curTime = Date.now();
            that.submit.className = 'imconfig-style-input-submit imconfig-style-input-submit-forbid';
            setTimeout(function() {
                that.submit.className = 'imconfig-style-input-submit';
            }, that.io.speed || 2000);
        });
    };
    ChatUI.prototype.updateInfo = function(info, num, total) {
        if (info) {
            this.info.style.backgroundImage = 'url(' + info.avatar + ')';
            this.info.innerText = info.name;
        }
        this.count.innerText = '当前在线:' + num + '人';
    };
    ChatUI.prototype.getHTML = function() {
        this.html = '\
            <div class="imconfig-style-main">\
                <div class="imconfig-style-control">\
                    <div class="imconfig-style-control-count"></div>\
                </div>\
                <div class="imconfig-style-self-msg"></div>\
                <div class="imconfig-style-left"></div>\
                <div class="imconfig-style-content">\
                    <div class="imconfig-style-content-ul"></div>\
                    <div class="imconfig-style-content-control">\
                        <div class="imconfig-style-control-lock">\
                            <div class="imconfig-style-control-lock-i"></div>\
                            <div class="imconfig-style-control-lock-text">滚屏</div>\
                        </div>\
                    </div>\
                    <div class="imconfig-style-content-input">\
                        <div class="imconfig-style-edit" contenteditable="true"></div>\
                        <div class="imconfig-style-input-submit" title="Ctrl+Enter"></div>\
                    </div>\
                </div>\
                <div class="imconfig-style-clearfix"></div>\
            </div>\
        ';
    };
    ChatUI.prototype.logout = function() {

    };

    function checkError() {
        if (err > 20) {
            return true;
        }
        return false;
    }

    function getCSS(url, cb) {
        //get style
        var style = document.createElement('link');
        style.setAttribute('rel', 'stylesheet');
        style.setAttribute('type', 'text/css');
        style.setAttribute('href', url);
        document.head.appendChild(style);
        style.onload = cb;
    }

    function getJs(url, cb) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = url;
        document.head.appendChild(script);
        script.onload = cb;
    }
    ChatUI.prototype.onChat = function(from, msg) {
        var el = document.createElement('div');
        el.className = 'imconfig-style-msgli';
        if (from.id === this.io.info.id) {
            el.className += " imconfig-style-self-msgli";
        }

        var avatar = document.createElement('div');
        avatar.className = 'imconfig-style-msgli-img';
        avatar.style.backgroundImage = 'url(' + from.avatar + ')';
        avatar.innerText = from.name;

        var text = document.createElement('div');
        text.className = 'imconfig-style-msgli-msg';
        text.innerText = msg.text;

        el.appendChild(avatar);
        el.appendChild(text);

        this.lis.push(el);
        if (this.lis.length > this.MaxLisNumber) {
            this.lis.shift().remove();
        }
        this.ul.appendChild(el);

        if (!this.lockRoller) {
            this.ul.scrollTop = this.ul.scrollHeight;
        }
    };

    function Chat(io, model) {
        var that = this;
        that.model = model;
        this.io = io('http://im.imconfig.com/chat?rn=0'); //io('http://127.0.0.1:8900/chat?rn=0'); //
        this.io.on('in', function(data) {
            that.speed = data.speed;
            that.info = data.info;
            that.model.updateInfo(data.info, data.number, data.total);
            that.number = data.number;
            that.total = data.total;
        });
        this.io.on('chat', this.chatCallback.bind(this));
        this.io.on('connect', function() {});
        this.io.on('connect_error', function() {
            console.log('connect_error');
        });
        this.io.on('connect_timeout', function() {
            console.log('connect_timeout');
        });
    }
    Chat.prototype.chat = function(msg, callback) {
        var that = this;
        this.io.emit('chat', {
            text: msg
        }, function(data, from, msg) {
            that.chatCallback(data, from, msg);
            callback(data);
        });
    };
    Chat.prototype.chatCallback = function(data, from, msg) {
        this.number = data.number;
        this.total = data.total;
        if (checkMsg(from, msg)) {
            this.model.onChat(from, msg);
            this.model.updateInfo(false, data.number, data.total);
        }
    };

    function checkMsg(from, msg) {
        return from && checkKey(from, ['id', 'name', 'avatar']) && msg && checkKey(msg, ['text']);
    }

    function checkKey(obj, k) {
        for (var i in k) {
            if (!(k[i] in obj)) {
                return false;
            }
        }
        return true;
    }
    return ChatUI;
});